package com.my.test.thread.ThreadPool;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

public class DefaultThreadPool<Job extends Runnable> implements ThreadPool<Job>{



	// 线程池最大限制数
	private static final int MAX_WORKER_NUMBERS = 10;

	// 线程池默认的数量
	private static final int DEFAULT_WORKER_NUMBERS = 5;

	// 线程池最小的数量
	private static final int MIN_WORKER_NUMBERS = 1;

	// 这是一个工作列表，将会向里面插入工作(接收提交的任务)生产者
	private final LinkedList<Job> jobs = new LinkedList<Job>();


	/**
	 * 利用类似 private static List<Task> taskQueue = Collections.synchronizedList(new LinkedList<Task>());
	 * 的方法可以得到本身不是线程安全的容易的线程安全的状态，但是要注意的是线程安全仅仅指的是如果直接使用它提供的函数，比如：queue.add(obj); 或者 queue.poll(obj);
	 * 这样我们自己不需要做任何同步。但如果是非原子操作，比如：
	 if(!queue.isEmpty()) {
	 queue.poll(obj);
	 }
	 我们很难保证，在调用了isEmpty()之后，poll()之前，这个queue没有被其他线程修改。
	 所以对于这种情况，我们还是需要自己同步：
	 synchronized(queue) {
	 if(!queue.isEmpty()) {
	 queue.poll(obj);
	 }
	 }
	 */
	// 工作者列表消费者(线程池)
	private final List<Worker> workers = Collections.synchronizedList(new ArrayList<Worker>());

	// 工作者线程的数量
	private int workerNum = DEFAULT_WORKER_NUMBERS;

	// 线程编号生成
	private AtomicLong threadNum = new AtomicLong();

	public DefaultThreadPool() {
		initializeWorkers(DEFAULT_WORKER_NUMBERS);
	}

	/**
	 * 初始化线程池
	 *
	 * num>MAX_WORKER_NUMBERS MAX_WORKER_NUMBERS
	 * num<MIN_WORKER_NUMBERS MIN_WORKER_NUMBERS
	 * num<MAX_WORKER_NUMBERS num
	 * @param num
	 */
	public DefaultThreadPool(int num) {
		workerNum = num > MAX_WORKER_NUMBERS?MAX_WORKER_NUMBERS:num <MIN_WORKER_NUMBERS?MIN_WORKER_NUMBERS:num;
		initializeWorkers(num);
	}

	// 执行一个job，这个job需要实现Runnable
	@Override
	public void execute(Job job) {
		if (job != null) {
			synchronized (jobs) {
				jobs.addLast(job);
				jobs.notify();// Object对象的方法
			}
		}
	}

	@Override
	public void shutdown() {
		for (Worker work : workers) {
			work.shuntdown();
		}
	}



	/**
	 * 增加工作者线程
	 */
	@Override
	public void addWorkers(int num) {
		synchronized (jobs) {
			// 限制新增的Worker数量不能超过最大值
			if (num + this.workerNum > MAX_WORKER_NUMBERS){
				num = MAX_WORKER_NUMBERS - this.workerNum;
			}
			initializeWorkers(num);
			this.workerNum+=num;
		}
	}

	/**
	 * 减少工作者线程
	 */
	@Override
	public void removeWorker(int num) {
		synchronized (jobs) {
			if (num >= this.workerNum) {
				throw new IllegalArgumentException();
			}
			// 按照给定的数量停止Worker
			int count = 0;
			while (count < num) {
				Worker worker = workers.get(count);
				if (workers.remove(worker)) {
					worker.shuntdown();
					count++;
				}
			}
		}
	}

	@Override
	public int getJobSize() {
		return jobs.size();
	}

	// 初始化工作者,启动workerNum数量大小线程
	private void initializeWorkers(int num) {
		for (int i = 0;i<num;i++) {
			Worker worker = new Worker();
			workers.add(worker);
			Thread thread = new Thread(worker,"Thread-Worker-" + threadNum.incrementAndGet());
			thread.start();
			System.out.println(Thread.currentThread().getName());
		}
	}

	/**
	 * 负责消费任务
	 * @author ThinkPad
	 *
	 */
	class Worker implements Runnable {

		// 是否工作
		private volatile boolean running = true;

		@Override
		public void run() {
			while(running) {
				Job job = null;
				synchronized (jobs) {
					while (jobs.isEmpty()) {
						try {
							jobs.wait();
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
					}
					// 取出一个job
					job = jobs.removeFirst();
				}
				if (job != null) {
					job.run();
				}
			}

		}

		public void shuntdown() {
			running = false;
		}
	}
	
	
	
}
